package m.framework.web;

import java.io.IOException;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import m.framework.controller.BaseController;
import m.framework.controller.ControllerMethod;
import m.framework.controller.CurrentUser;
import m.framework.controller.ResponseView;
import m.framework.exception.Message;
import m.framework.utils.JsonUtil;
import m.framework.utils.LogUtil;
import m.framework.web.json.AjaxJson;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter;

import com.alibaba.fastjson.serializer.SerializerFeature;

public class MyHandlerAdapter extends AnnotationMethodHandlerAdapter {
	private static Logger log = LoggerFactory.getLogger(MyHandlerAdapter.class);

	protected ModelAndView invokeHandlerMethod(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
		
		BaseController controller = (BaseController) handler;
		String methodName = getMethodName(request);
		
		ControllerMethod method=null;
		try{
			method = new ControllerMethod(controller, methodName);
		}catch(Exception ex){
			log.error("获取方法"+controller.getClass().getName()+"."+methodName+"失败",ex);
			return error(request,response,ex);
		}
		
		Object obj=null;
		try{
			RequestMap para = new RequestMap(request);
			log.debug("准备执行方法"+controller.getClass().getName()+"."+methodName);
			obj = method.execute(para, controller.getUser());
			//自己搞定的view
			if(obj instanceof ResponseView){
				((ResponseView) obj).parseResponse(response);
				return null;
			}
		}catch(Exception ex){
			Throwable cause=LogUtil.getCause(ex);
			if(!(cause instanceof Message)){
				log.error("执行"+controller.getClass().getSimpleName()+"."+methodName
						+"方法出错",ex);
			}
			return error(request, response, ex);
		}
		
		
		if(request.getRequestURI().endsWith("json")){
			writeJson(response,obj);
			return null;
		}
		
		return method.createView(obj,request.getParameter("forward"));
	}

	//返回错误页面
	private ModelAndView error(HttpServletRequest request, HttpServletResponse response, Exception exception) throws IOException {
		if(request.getRequestURI().endsWith("json")){
			writeJson(response,exception);
			return null;
		}
		return ControllerMethod.errorPage(exception);
	}

	private void writeJson(HttpServletResponse response, Object obj) throws IOException {
		AjaxJson jo=new AjaxJson(obj);
		String json=JsonUtil.toJson(jo,SerializerFeature.WriteDateUseDateFormat);
		log.debug("向页面写json:\n"+json);
		response.getWriter().write(json);
	}
	

	// 通过url获取方法名,所有请求格式都是/model/operate.jsp,这里的operate就是方法名
	private String getMethodName(HttpServletRequest request) {
		String url = request.getRequestURI();
		int point = url.lastIndexOf('.');
		int line2 = url.lastIndexOf('/');
		return url.substring(line2 + 1, point);
	}

}
